package com.atguigu.gmall.mq.receiver;

import com.rabbitmq.client.Channel;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @author: atguigu
 * @create: 2023-01-13 11:26
 */
@Slf4j
@Component
public class ConfirmReceiver {


    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 创建队列交换器方式一：通过@RabbitListener 声明队列，交换器绑定路由键
     * 监听普通消息
     * @param msg 消息内容
     * @param message 消息对象封装信息很多
     * @param channel 信道 用于应答
     */
    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange("exchange.confirm"),
            value = @Queue("queue.confirm"),
            key = {"routing.confirm"}
    ))
    public void processMsg(String msg, Message message, Channel channel){
        try {
            //在消费者端 找到消息内容的唯一标识：例如订单流水ID
            //借助Redis setnx key不存在才会存储成功
            Boolean flag = redisTemplate.opsForValue().setIfAbsent(msg, "0", 10, TimeUnit.MINUTES);
            if(!flag){
                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                return;
            }
            log.info("【ConfirmReceiver】监听到消息：{}", msg);
            //消费者必须要应答，如果不应答消息在broker服务器显示未ready
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【ConfirmReceiver】监听消息业务失败");
        }
    }


}
